/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
/*                                                                         */
/* Redistribution and use in source and binary forms, with or without      */
/* modification, are permitted provided that the following conditions      */
/* are met:                                                                */
/*                                                                         */
/*    1. Redistributions of source code must retain the above copyright    */
/* notice, this list of conditions and the following disclaimer.           */
/*    2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the     */
/* documentation and/or other materials provided with the distribution.    */
/*                                                                         */
/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "ath.h"

void
ath_phys_update(ath_phys *phys, ath_upd_phys *phys_upd)
{
    ath_lock *lock;
    apr_time_t mtime;
    ath_engine *engine = ath_engine_get();
    
    lock = ath_lock_for_idx(phys->lock_idx);
    ath_lock_acquire(lock);
    mtime = apr_time_now();
    /* don't update mtime if required field wasn't updated */
    if ((engine->expect_update == 1)
	&& (engine->expect_update_field != ATH_ALGO_NON))
      {
	  if (ath_phys_upd_field_updated(phys_upd, 
					 engine->expect_update_field))
	      phys->mtime = mtime;
      }
    else
	phys->mtime = mtime;
    if (phys_upd->on_u)
	phys->on = phys_upd->on;
    if (phys_upd->up_u)
	phys->up = phys_upd->up;
    if (phys_upd->cpu_u)
	phys->cpu = phys_upd->cpu;
    if (phys_upd->net_u)
	phys->net = phys_upd->net;
    if (phys_upd->ld_u)
	phys->ld = phys_upd->ld;
    if (phys_upd->mem_u)
	phys->mem = phys_upd->mem;
    if (phys_upd->disk_u)
	phys->disk = phys_upd->disk;
    if (phys_upd->cus0_u)
	phys->cus0 = phys_upd->cus0;
    if (phys_upd->cus1_u)
	phys->cus1 = phys_upd->cus1;
    if (phys_upd->cus2_u)
	phys->cus2 = phys_upd->cus2;
    if (phys_upd->cus3_u)
	phys->cus3 = phys_upd->cus3;
    if (phys_upd->cus4_u)
	phys->cus4 = phys_upd->cus4;
    if (phys_upd->cus5_u)
	phys->cus5 = phys_upd->cus5;
    if (phys_upd->cus6_u)
	phys->cus6 = phys_upd->cus6;
    if (phys_upd->cus7_u)
	phys->cus7 = phys_upd->cus7;
    if (phys_upd->cus8_u)
	phys->cus8 = phys_upd->cus8;
    if (phys_upd->cus9_u)
	phys->cus9 = phys_upd->cus9;
    ath_lock_release(lock);
}

/* see also ath_phys_clone_from_str 
   additional checks here to make safe for shm overwrite 
*/
ath_phys * 
ath_phys_from_str(apr_pool_t *pool, char * str_phys)
{
    ath_phys *phys = NULL;
    ath_lock *lock;
    ath_phys *phys_mirr = NULL;
    ath_engine *engine = ath_engine_get();
    ASSERT(str_phys);

    phys_mirr = ath_phys_clone_from_str(pool, str_phys);

	  /* verify valid indeces */
    if ((phys_mirr)
	&& ((phys_mirr->idx < 0) || (phys_mirr->idx > engine->phys_count)))
      {
	  ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
		       "Phys index out of bounds: [%d]", phys_mirr->idx); 
	  phys_mirr = NULL;
      }
    if (phys_mirr)
	phys = ath_phys_raw_for_idx(phys_mirr->idx);
    if (phys)
      {
	  if ((phys->lock_idx < 0) 
	      || (phys->lock_idx > ath_lock_mux_init_count()))
	      ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
			   "Impossible lock idx: [%d]", phys->lock_idx); 
	  else
	    {
		lock = ath_lock_for_idx(phys->lock_idx);
		ath_lock_acquire(lock);
		ath_phys_copy(phys, phys_mirr);
		ath_lock_release(lock);
	    }
      }
    else
	ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, ATH_EPHYSSTR);

    return phys;
}
